home *** CD-ROM | disk | FTP | other *** search
/ Do It! 2 / Do It! Volume 2.iso / for_amiga / diavolodemo / db302dem.lha / Misc / API / DBCLICtrl / DBCLICtrl.c < prev    next >
C/C++ Source or Header  |  1995-10-11  |  25KB  |  707 lines

  1. /* Diavolo CLI Control */
  2.  
  3. #define     VERSION     "1.1"
  4.  
  5. /*
  6.  
  7.     This file is meant as an example for programming the Diavolo Application Programming
  8.     Interface.
  9.  
  10.     It can be used to start and monitor a backup procedure from the CLI. Therefor it is
  11.     possible to make automated backups with Cron tables.
  12.  
  13.  
  14.     This source was written and tested using SAS/C 6.55
  15.  
  16.     For a detailed documentation of the API see DiavoloAPI.h and DiavoloPrefs.h.
  17.  
  18.  
  19.     If you want to print this file, set your printer to 136 characters per line (condensed font).
  20.  
  21.  
  22.     © 1995 Martin Korndörfer.
  23.  
  24.     History:
  25.  
  26.     1.1
  27.     ---
  28.  
  29.     - Disabled SAS Break Handling
  30.     - Adapted to new API Port name
  31. */
  32.  
  33. /* *********************************************************************** */
  34. /* *********************************************************************** */
  35. /*                                                                         */
  36. /* Includes                                                                */
  37. /*                                                                         */
  38. /* *********************************************************************** */
  39. /* *********************************************************************** */
  40.  
  41.  
  42. #include <clib/locale_protos.h>             /* Contains all prototypes for Amiga functions. May
  43.                                                have a different name when using another compiler */
  44.  
  45.  
  46. #include <dos/dos.h>
  47. #include <dos/dostags.h>
  48. #include <exec/exec.h>
  49. #include <stdio.h>
  50. #include <string.h>
  51.  
  52. #include "sas:Diavolo/DiavoloPrefs.h"       /* Contains documented preference structure and constants */
  53. #include "sas:Diavolo/DiavoloAPI.h"         /* Structures, constants and documentation of Diavolo API */
  54.  
  55.  
  56. int CXBRK(void)     { return(0); }          /* Disable Lattice Ctrl-C Handl. */
  57. void __regargs __chkabort(void)  { }
  58.  
  59.  
  60. /* *********************************************************************** */
  61. /* *********************************************************************** */
  62. /*                                                                         */
  63. /* ReadArgs() definitions                                                  */
  64. /*                                                                         */
  65. /* *********************************************************************** */
  66. /* *********************************************************************** */
  67.  
  68. /* This is the CLI template for DiavoloCLICtrl.
  69.  
  70.    Filter:          Filename of filter to select files and partitions to backup.
  71.                     Must be given.
  72.  
  73.    Config:          Name of a Diavolo configuration file. This file will be used for
  74.                     all options as for the backup destination as well.
  75.                     Must be given.
  76.  
  77.    Name:            Name for backup.
  78.  
  79.    AutoCompare:     Compare backup after completion
  80.  
  81.    Overwrite:       Only for backup to SCSI tape: Number of backup to overwrite.
  82.                     0: Ask user
  83.                     1: Overwrite tape from beginning
  84.                     2..x: Overwrite beginning with backup no. x
  85.                     If not given: Append to tape.
  86.  
  87.    Password:        Password for the backup. Can be omitted.
  88.  
  89.    Encode:          Only valid with a password set. Encode the backup with the given
  90.                     backup.
  91.  
  92.    DoNotStartDiavolo: The program will try to start Diavolo when it is not present.
  93.                       If this options is set, the program will fail instead.
  94. */
  95.  
  96. #define ARG_TEMPLATE        "Filter/A,Config/A,Name,AutoCompare/S,Overwrite/K/N,PW=Password/K,Encode/S,ER=ErrorReport,FR=FileReport,DoNotStartDiavolo/S"
  97. #define ARG_MAX             10
  98.  
  99. #define ARG_FILTER          0
  100. #define ARG_CONFIG          1
  101. #define ARG_NAME            2
  102. #define ARG_AUTOCOMPARE     3
  103. #define ARG_OVERWRITE       4
  104. #define ARG_PASSWORD        5
  105. #define ARG_ENCODE          6
  106. #define ARG_ERRORREP        7
  107. #define ARG_FILEREP         8
  108. #define ARG_DONTSTARTDB     9
  109.  
  110. #define ARG_FILTER_DEF      NULL
  111. #define ARG_CONFIG_DEF      NULL
  112. #define ARG_NAME_DEF        NULL
  113. #define ARG_AUTOCOMPARE_DEF FALSE
  114. #define ARG_OVERWRITE_DEF   NULL
  115. #define ARG_PASSWORD_DEF    NULL
  116. #define ARG_ENCODE_DEF      FALSE
  117. #define ARG_ERRORREP_DEF    NULL
  118. #define ARG_FILEREP_DEF     NULL
  119. #define ARG_DONTSTARTDB_DEF FALSE
  120.  
  121. LONG                        ArgArray[ARG_MAX];
  122.  
  123.  
  124. /* *********************************************************************** */
  125. /* *********************************************************************** */
  126. /*                                                                         */
  127. /* Global variables                                                        */
  128. /*                                                                         */
  129. /* *********************************************************************** */
  130. /* *********************************************************************** */
  131.  
  132. #define FETT        "\x1b[1m"               /* For CLI output, boldface on and off */
  133. #define NORM        "\x1b[0m"
  134.  
  135. struct      MsgPort         *MyReplyPort;   /* Global Reply Port. Will be used by Diavolo to send its
  136.                                                messages to the client */
  137.  
  138. struct      MsgPort         *APIPort;       /* API Port of Diavolo Backup. Global message port which
  139.                                                must be used to send messages to Diavolo */
  140.  
  141. BOOL                        Quit;           /* TRUE: Quit requested by Diavolo */
  142.  
  143. BOOL                        Break;          /* TRUE: Ctrl-C pressed */
  144.  
  145. char        Version[] =     "$VER:DBCLICtrl "VERSION" "__AMIGADATE__;
  146.  
  147.  
  148. /* *********************************************************************** */
  149. /* *********************************************************************** */
  150. /*                                                                         */
  151. /* Forward function declarations                                           */
  152. /*                                                                         */
  153. /* *********************************************************************** */
  154. /* *********************************************************************** */
  155.  
  156.  
  157. void    CheckDAPIMsg(struct DiavoloAPIMsg   *APIMsg);
  158.  
  159.  
  160. /* *********************************************************************** */
  161. /* *********************************************************************** */
  162. /*                                                                         */
  163. /* Frame functions, use them in your code                                  */
  164. /*                                                                         */
  165. /* *********************************************************************** */
  166. /* *********************************************************************** */
  167.  
  168. void    CheckRequest(struct    DiavoloAPIMsg   *APIMsg)
  169.  
  170. /* Will be used to process incoming request messages. After a client has made contact with
  171.    Diavolo, before a requester is displayed to the user, a message will be sent to the client.
  172.    The client can answer this request itself, so the user never sees the request, or make Diavolo
  173.    display the request as normal. Anyway, the client MUST reply the request as fast as possible,
  174.    so the message port must be always watched for incoming messages. If the client does not reply
  175.    a message, there could be a deadlock (Diavolo waiting for client and client waiting for
  176.    Diavolo).
  177.  
  178.    Modify this routine to customize the clients reaction to requesters. Look at the DAPI_RC_...
  179.    defines at the end of DiavoloAPI.h for all possible request codes and their meaning.
  180.  
  181. */
  182.  
  183. {
  184.     ULONG                       RetVal;
  185.     static BOOL                 DirDiskRequested = FALSE;
  186.  
  187.  
  188.     /* This switch/case statement decides what to do with the requester. */
  189.  
  190.     switch(APIMsg->DAPI_Arg1)
  191.     {
  192.         /* The following requests will not be displayed to the user. Instead Diavolo reacts as if
  193.            the user had pressed RETRY. */
  194.  
  195.         case DAPI_RC_INSERTDISK:        /* Insert disk in any drive... */
  196.         case DAPI_RC_BACKDISK:          /* This disk contains another backup... */
  197.         case DAPI_RC_DOSDISK:           /* This disk is DOS formatted ... */
  198.         case DAPI_RC_ALIENTAPE:         /* This tape contains unreadable data or is empty ... */
  199.         case DAPI_RC_FILEEXISTS:        /* Backup file already exists, overwrite? ... */
  200.  
  201.             RetVal = 1;                 /* RetVal will be used as a replycode to Diavolo.
  202.                                            1 means the leftmost option, in these cases RETRY. */
  203.             break;
  204.  
  205.         case DAPI_RC_INSERTDIRDISK:     /* Insert first disk in any drive.
  206.                                            This request can be replied with 1 when it is made the
  207.                                            first time. Maybe the first disk is already present.
  208.                                            If the request repeats, show it to the user though. */
  209.             if(DirDiskRequested)
  210.                 RetVal = ~0;
  211.             else
  212.             {
  213.                 RetVal = 1;
  214.                 DirDiskRequested = TRUE;
  215.             }
  216.             break;
  217.  
  218.         default:                        /* In all other cases... */
  219.  
  220.             RetVal = ~0;                /* A RetVal of ~0 (bitwise NOT 0, in other words all bits set)
  221.                                            means that Diavolo should display the requester as normal */
  222.     }
  223.  
  224.     APIMsg->DAPI_Arg1 = RetVal;         /* Return the message with RetVal set in Arg1 */
  225.     ReplyMsg(APIMsg);
  226. }
  227.  
  228.  
  229.  
  230.  
  231. void    CheckDAPIMsg(struct DiavoloAPIMsg   *APIMsg)
  232.  
  233. /* Check incoming messages. */
  234.  
  235. {
  236.     /* Look if the received message was a reply. Normally replies will only return after you've sended
  237.        a message to Diavolo in the first place. This example is written in a way, that every
  238.        routine knows its sent messages and handles their replies itself, so this generic routine
  239.        should never has to handle replies. */
  240.     if(APIMsg->DAPI_Message.mn_Node.ln_Type == NT_REPLYMSG)
  241.     {
  242.         printf("Reply received. Don't know original message. ERROR!\n");
  243.     }
  244.  
  245.     else
  246.     {
  247.         /* What kind of message is this? */
  248.  
  249.         switch(APIMsg->DAPI_Command)
  250.         {
  251.             case    DAPI_REQUEST:
  252.                 /* Diavolo has a request. CheckRequest (see above) handles them */
  253.                 CheckRequest(APIMsg);
  254.                 break;
  255.  
  256.             case    DAPI_CLOSEDOWN:
  257.                 /* Diavolo is closing down. The client is informed that it has to cut down
  258.                    the link to Diavolo, so it can complete the closedown. */
  259.  
  260.                 Quit = TRUE;            /* Set global Quit flag to TRUE */
  261.                 ReplyMsg(APIMsg);       /* Return message */
  262.                 break;
  263.  
  264.             default:
  265.                 /* Another - unknown - message has arrived. Diavolo only sends the two
  266.                    messages handled above or replies. */
  267.  
  268.                 printf("Unknown message. Command: %lx\n",APIMsg->DAPI_Command);
  269.                 ReplyMsg(APIMsg);
  270.                 break;
  271.         }
  272.     }
  273. }
  274.  
  275.  
  276.  
  277. BOOL    DoCommand(struct DiavoloAPIMsg *APIMsg)
  278.  
  279. /* Send a command to Diavolo and wait for its completion (its reply).
  280.  
  281.    This routine handles all incoming message (also requests) and waits until the command
  282.    was replied.
  283.  
  284.    Use this for all commands you want to send synchronously (which should be most). You
  285.    cannot use them for asynchronous command, which are used to initiate an operation.
  286.    These are DAPI_STARTBACKUP, DAPI_STARTSCAN and DAPI_STARTRESTORE. This application
  287.    doesn't need to use these commands asynchronously, though, so they are handled by
  288.    this routine anyway.
  289.  
  290.    The parameter APIMsg must be filled with the correct parameters you want to send to
  291.    Diavolo (also the command code itself). After the routine replies you can find the
  292.    result codes set by Diavolo in the same structure.
  293. */
  294.  
  295. {
  296.     struct  DiavoloAPIMsg       *Reply;
  297.     BOOL                        Ok;
  298.  
  299.     /* Set Replyport of the message to send to the global client message port */
  300.     APIMsg->DAPI_Message.mn_ReplyPort = MyReplyPort;
  301.  
  302.     /* Send the message to Diavolo's API Port */
  303.     PutMsg(APIPort, APIMsg);
  304.  
  305.     do
  306.     {
  307.         /* This is a generic method of waiting for a message. If you want to check more
  308.            than one message port, you'll have to add more bits to the Wait() mask. */
  309.  
  310.         while(! (Reply = (struct DiavoloAPIMsg *)GetMsg(MyReplyPort)))
  311.             Wait(1l << MyReplyPort->mp_SigBit);
  312.  
  313.         if(Reply->DAPI_Message.mn_Node.ln_Type != NT_REPLYMSG || Reply != APIMsg)
  314.         {
  315.             /* The received message wasn't the reply for our own message, so process it */
  316.  
  317.             CheckDAPIMsg(Reply);
  318.             Reply = NULL;           /* No, we're not finished yet */
  319.         }
  320.         else
  321.         {
  322.             /* Our message has been replied. Fine, now look if there was an error
  323.                set in the reply: */
  324.  
  325.             switch(Reply->DAPI_Errorcode)
  326.             {
  327.                 case DAPI_EC_NOERROR:
  328.                     /* Everything was fine! */
  329.  
  330.                     Ok = TRUE;
  331.                     break;
  332.  
  333.                 case DAPI_EC_INUSE:
  334.                     /* Diavolo's messageport is in use by another application */
  335.  
  336.                     printf("Reply: In Use error\n");
  337.                     Ok = FALSE;
  338.                     break;
  339.  
  340.                 case DAPI_EC_NOTAVAILABLE:
  341.                     /* The sent command is not available at this moment or entirely unknown */
  342.  
  343.                     printf("Reply: Command not available!\n");
  344.                     Ok = FALSE;
  345.                     break;
  346.  
  347.                 case DAPI_EC_NOTMETYET:
  348.                     /* You have not intiated the dialogue using DAPI_RENDEZVOUS yet */
  349.  
  350.                     printf("Reply: Programs not met yet!\n");
  351.                     Ok = FALSE;
  352.                     break;
  353.  
  354.                 case DAPI_EC_INVALIDCONFIG:
  355.                     /* The new configuration was invalid */
  356.  
  357.                     printf("Reply: Invalid config!\n");
  358.                     Ok = FALSE;
  359.                     break;
  360.  
  361.                 case DAPI_EC_SELECTFAILED:
  362.                     /* The selection (in DAPI_BACKSELECT and DAPI_RESTSELECT) failed */
  363.  
  364.                     printf("Reply: Selection failed. Code: %ld!\n", Reply->DAPI_Arg1);
  365.                     Ok = FALSE;
  366.                     break;
  367.  
  368.                 case DAPI_EC_OPPENDING:
  369.                     /* You cannot cut the connection (using DAPI_GOODBYE) while a client
  370.                        intiated operation is in progress. Cancel the operation first! */
  371.  
  372.                     printf("Reply: Operation pending, Goodbye not possible!\n");
  373.                     Ok = FALSE;
  374.                     break;
  375.  
  376.                 case DAPI_EC_OPFAILED:
  377.                     /* The oepration failed */
  378.  
  379.                     printf("Reply: Operation failed, Code: %ld!\n",Reply->DAPI_Arg1);
  380.                     Ok = FALSE;
  381.                     break;
  382.  
  383.                 default:
  384.                     printf("Unknown errorcode: %ld\n",Reply->DAPI_Errorcode);
  385.                     Ok = FALSE;
  386.             }
  387.         }
  388.     }
  389.     while(Reply == NULL);
  390.     return(Ok);
  391. }
  392.  
  393.  
  394.  
  395.  
  396. int main(int argc, char **argv)
  397.  
  398. {
  399.     struct      DiavoloAPIMsg   APIMsg;
  400.     BOOL                        Ok, DBStarted;
  401.     struct      RDArgs          *ArgRDArgs;
  402.     char                        RendezvousName[30];
  403.  
  404.  
  405.     /* Reset argument array with the default values for ReadArgs() */
  406.  
  407.     ArgArray[ARG_FILTER] = ARG_FILTER_DEF;
  408.     ArgArray[ARG_CONFIG] = ARG_CONFIG_DEF;
  409.     ArgArray[ARG_NAME] = ARG_NAME_DEF;
  410.     ArgArray[ARG_AUTOCOMPARE] = ARG_AUTOCOMPARE_DEF;
  411.     ArgArray[ARG_OVERWRITE] = ARG_OVERWRITE_DEF;
  412.     ArgArray[ARG_PASSWORD] = ARG_PASSWORD_DEF;
  413.     ArgArray[ARG_ENCODE] = ARG_ENCODE_DEF;
  414.     ArgArray[ARG_ERRORREP] = ARG_ERRORREP_DEF;
  415.     ArgArray[ARG_FILEREP] = ARG_FILEREP_DEF;
  416.     ArgArray[ARG_DONTSTARTDB] = ARG_DONTSTARTDB_DEF;
  417.  
  418.  
  419.     /* Call ReadArgs() to parse and interprete the command line parameters */
  420.  
  421.     printf(FETT"DBCLICtrl"NORM" - Diavolo Backup Command Line Interface Control\n");
  422.     printf(FETT"V "VERSION" © 1995"NORM" Martin Korndörfer\n\n");
  423.  
  424.     if(! (ArgRDArgs = ReadArgs(ARG_TEMPLATE,ArgArray,NULL)))
  425.     {
  426.         printf("Wrong argument(s)!\n\n");
  427.         printf("Template: "FETT"%s %s"NORM"\n\n",argv[0],ARG_TEMPLATE);
  428.         printf(FETT"Usage: %s"NORM" Filter Config [BackupName] [AUTOCOMPARE] [OVERWRITE x]\n",argv[0]);
  429.         printf("       [PW Password] [ENCODE] [ER File] [FR File] [DONOTSTARTDIAVOLO]\n\n");
  430.         printf("  "FETT"Parameters:"NORM" \n\n");
  431.         printf("    "FETT"Filter"NORM"              Filename of filter for file selection\n");
  432.         printf("    "FETT"Config"NORM"              Filename of configuration file\n");
  433.         printf("    "FETT"BackupName"NORM"          Name of Backup (optional)\n");
  434.         printf("    "FETT"AUTOCOMPARE"NORM"         Compare backup (switch)\n");
  435.         printf("    "FETT"OVERWRITE x"NORM"         SCSITape: x=Backupnr. to overwrite, 0 ask,\n");
  436.         printf("                                  append to EOT if omitted\n");
  437.         printf("    "FETT"PW Password"NORM"         Password to protect backup with\n");
  438.         printf("    "FETT"ENCODE"NORM"              Only with PW set: Encode backup\n");
  439.         printf("    "FETT"ER File"NORM"             Write error report to file\n");
  440.         printf("    "FETT"FR File"NORM"             Write file list report to file\n");
  441.         printf("    "FETT"DONOTSTARTDIAVOLO"NORM"   Do not try to start Diavolo if not present\n\n");
  442.  
  443.         return(20);
  444.     }
  445.  
  446.  
  447.     /* First create our own message port */
  448.  
  449.     if(! (MyReplyPort = CreateMsgPort()))
  450.     {
  451.         printf("Error creating own message port!\n");
  452.         return(30);         /* Failed */
  453.     }
  454.  
  455.  
  456.     /* Use forbid to secure the FindPort Operation (suggested in Exex autodocs) */
  457.  
  458.     Forbid();
  459.  
  460.  
  461.     /* Look for Diavolo message port. This will only look for Diavolo.1 */
  462.  
  463.     sprintf(RendezvousName,RENDEZVOUS_NAME,1);
  464.  
  465.     if(! (APIPort = FindPort(RendezvousName)))
  466.     {
  467.         Permit();
  468.         /* Message port not found. Now, if not forbidden, start Diavolo */
  469.  
  470.         if(ArgArray[ARG_DONTSTARTDB])
  471.         {
  472.             DeleteMsgPort(MyReplyPort);
  473.             printf("Diavolo port not found!\n");
  474.             return(20);
  475.         }
  476.  
  477.  
  478.         /* Diavolo detaches itself from the parent task, so there is no need to start Diavolo
  479.            asynchronously. */
  480.  
  481.         if(SystemTags("Diavolo",
  482.                     NP_StackSize,       10000,
  483.                     NP_Name,            "Diavolo",
  484.                     TAG_DONE))
  485.         {
  486.             printf("Couldn't start Diavolo!\n");
  487.             DeleteMsgPort(MyReplyPort);
  488.             return(20);
  489.         }
  490.  
  491.         DBStarted = TRUE;       /* Diavolo was started by DBCLICtrl */
  492.  
  493.         Delay(100);             /* Wait 2 seconds until DB has initialized its rendezvous port */
  494.  
  495.  
  496.         Forbid();
  497.  
  498.         /* Look for Diavolo message port */
  499.  
  500.         if(! (APIPort = FindPort(RendezvousName)))
  501.         {
  502.             Permit();
  503.             printf("Couldn't find Diavolo API port!\n");
  504.             DeleteMsgPort(MyReplyPort);
  505.             return(20);
  506.         }
  507.     }
  508.     else
  509.         DBStarted = FALSE;
  510.  
  511.  
  512.     Permit();
  513.  
  514.     /* Before any action can take place, The client must first make a connection
  515.        with Diavolo.
  516.  
  517.        Diavolo will use the given ReplyPort to send its messages to the client
  518.        as long as the connection is active. */
  519.  
  520.     APIMsg.DAPI_Command = DAPI_RENDEZVOUS;
  521.     Ok = DoCommand(&APIMsg);
  522.  
  523.     if(! Ok)
  524.         printf("Rendezvous with Diavolo failed!\n");
  525.     else
  526.     {
  527.         /* While the client is preparing an operation, any user interference might
  528.            have unwanted results, so it's better to disable the user interface. */
  529.  
  530.         APIMsg.DAPI_Command = DAPI_LOCKUI;
  531.         APIMsg.DAPI_Arg1 = TRUE;                /* Lock active */
  532.         Ok = DoCommand(&APIMsg);
  533.  
  534.         if(! Ok)
  535.             printf("Lock user interface failed!\n");
  536.     }
  537.  
  538.     if(Ok)
  539.     {
  540.         /* This function initiates the backup, just the same as when the user presses
  541.            the button "Backup" in the main menu. The Device Selection window will open
  542.            then. */
  543.  
  544.         APIMsg.DAPI_Command = DAPI_INITBACKUP;
  545.         Ok = DoCommand(&APIMsg);
  546.         if(! Ok)
  547.             printf("Backup initialization failed!\n");
  548.     }
  549.  
  550.     if(Ok)
  551.     {
  552.         /* There may be a previous file selection active in Diavolo. Before the client
  553.            makes its own selection, it should make sure that there is no previous selection
  554.            active. */
  555.  
  556.         APIMsg.DAPI_Command = DAPI_CLEARLISTS;
  557.         Ok = DoCommand(&APIMsg);
  558.         if(! Ok)
  559.             printf("Clearing selection lists failed!\n");
  560.     }
  561.  
  562.     if(Ok)
  563.     {
  564.         /* The configuration file given in the arguments must be loaded. */
  565.  
  566.         APIMsg.DAPI_Command = DAPI_LOADCONFIG;
  567.         APIMsg.DAPI_Ptr1 = (APTR)ArgArray[ARG_CONFIG];
  568.         Ok = DoCommand(&APIMsg) && APIMsg.DAPI_Arg1;    /* Success will be reported in Arg1 */
  569.         if(! Ok)
  570.             printf("Couldn't read configuration file!\n");
  571.     }
  572.  
  573.     if(Ok)
  574.     {
  575.         /* Use the specified filter file to make the selections. */
  576.  
  577.         APIMsg.DAPI_Command = DAPI_USEFILTER;
  578.         APIMsg.DAPI_Ptr1 = (APTR)ArgArray[ARG_FILTER];
  579.         Ok = DoCommand(&APIMsg);
  580.         if(Ok)
  581.         {
  582.             printf("Files selected: %ld, Size of backup: %ld\n",APIMsg.DAPI_Arg3,APIMsg.DAPI_Arg4);
  583.             Ok = (APIMsg.DAPI_Arg4 != 0);
  584.         }
  585.         if(! Ok)
  586.             printf("Fileselection failed!\n");
  587.     }
  588.  
  589.     if(Ok)
  590.     {
  591.         /* Before starting the backup procedure itself, the user interface lock should be
  592.            removed, so that the user has a chance of interrupting the backup. */
  593.  
  594.         APIMsg.DAPI_Command = DAPI_LOCKUI;
  595.         APIMsg.DAPI_Arg1 = FALSE;                /* Lock not active */
  596.         Ok = DoCommand(&APIMsg);
  597.  
  598.         if(! Ok)
  599.             printf("Unlock user interface failed!\n");
  600.     }
  601.  
  602.     if(Ok)
  603.     {
  604.         /* This command now starts the backup procedure. All parameter normally given
  605.            by the user before starting the backup (i.e. Backup name, password etc.)
  606.            must be given through this command. The message will not be replied until
  607.            the backup procedure is complete or cancelled. */
  608.  
  609.         APIMsg.DAPI_Command = DAPI_STARTBACKUP;
  610.         APIMsg.DAPI_Arg1 = ArgArray[ARG_PASSWORD] != NULL;      /* Use PW if parameter given */
  611.         APIMsg.DAPI_Arg2 = (BOOL)ArgArray[ARG_ENCODE];
  612.         if(ArgArray[ARG_OVERWRITE])
  613.             APIMsg.DAPI_Arg3 = *((LONG *)ArgArray[ARG_OVERWRITE]);
  614.         else
  615.             APIMsg.DAPI_Arg3 = ~0;          /* Append */
  616.  
  617.         if(ArgArray[ARG_NAME])
  618.             APIMsg.DAPI_Ptr1 = (APTR)ArgArray[ARG_NAME];
  619.         else
  620.             APIMsg.DAPI_Ptr1 = "Automated backup by DiavoloCLICtrl";
  621.  
  622.         APIMsg.DAPI_Ptr2 = (APTR)ArgArray[ARG_PASSWORD];
  623.  
  624.         Ok = DoCommand(&APIMsg);
  625.         if(Ok)
  626.             printf("Time for backup: %ld seconds\n",APIMsg.DAPI_Arg3);
  627.         else
  628.             printf("Backup procedure failed!\n");
  629.     }
  630.  
  631.     if(Ok && ArgArray[ARG_AUTOCOMPARE])
  632.     {
  633.         /* The backup procedure has been completed, so if the respective option was
  634.            set in the command line, start the auto compare procedure. */
  635.  
  636.         APIMsg.DAPI_Command = DAPI_COMPAREBACKUP;
  637.  
  638.         Ok = DoCommand(&APIMsg);
  639.         if(Ok)
  640.             printf("Time for compare: %ld seconds\n",APIMsg.DAPI_Arg2);
  641.         else
  642.             printf("Compare procedure failed!\n");
  643.     }
  644.  
  645.     if(Ok && ArgArray[ARG_ERRORREP])
  646.     {
  647.         /* Eventually, after all procedures have been completed, and the respective
  648.            option was given, create the error report */
  649.  
  650.         APIMsg.DAPI_Command = DAPI_CREATEREPORT;
  651.         APIMsg.DAPI_Arg1 = FALSE;           /* Create errorlist */
  652.         APIMsg.DAPI_Ptr1 = (APTR)ArgArray[ARG_ERRORREP];
  653.  
  654.         Ok = DoCommand(&APIMsg);
  655.         if(! Ok)
  656.             printf("Creation of error report failed!\n");
  657.     }
  658.  
  659.     if(Ok && ArgArray[ARG_FILEREP])
  660.     {
  661.         /* ... and the filelist report */
  662.  
  663.         APIMsg.DAPI_Command = DAPI_CREATEREPORT;
  664.         APIMsg.DAPI_Arg1 = TRUE;           /* Create filelist */
  665.         APIMsg.DAPI_Arg2 = TRUE;           /* Use wide format */
  666.         APIMsg.DAPI_Ptr1 = (APTR)ArgArray[ARG_FILEREP];
  667.  
  668.         Ok = DoCommand(&APIMsg);
  669.         if(! Ok)
  670.             printf("Creation of filelist report failed!\n");
  671.     }
  672.  
  673.  
  674.     /* The following commands should be executed, whether an error occured or not */
  675.  
  676.  
  677.     /* Back to main menu */
  678.  
  679.     APIMsg.DAPI_Command = DAPI_MAINMENU;
  680.     DoCommand(&APIMsg);
  681.  
  682.  
  683.     /* Quit Diavolo Backup, only if started by DBCLICtrl */
  684.  
  685.     if(DBStarted)
  686.     {
  687.         APIMsg.DAPI_Command = DAPI_QUIT;
  688.         DoCommand(&APIMsg);
  689.     }
  690.  
  691.  
  692.     /* Close down connection with Diavolo. This command MUST be given, if the client has
  693.        connected with DAPI_RENDEZVOUS. If this command is not given, Diavolo will be unable
  694.        to remove itself from memory and no other client can connect to Diavolo. */
  695.  
  696.     APIMsg.DAPI_Command = DAPI_GOODBYE;
  697.     DoCommand(&APIMsg);
  698.  
  699.     DeleteMsgPort(MyReplyPort);
  700.     FreeArgs(ArgRDArgs);
  701.  
  702.     if(Ok)
  703.         return(0);
  704.     else
  705.         return(10);
  706. }
  707.